﻿using System;
using System.ComponentModel;
using DataService.Enums;
using DataService.Structs;

namespace DataService;

public sealed class ComplexCondition : ConditionBase, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public override string Value
    {
        get
        {
            return Convert.ToString(_current.AlarmValue);
        }
    }

    public ComplexCondition(int id, string source, string comment, float deadBand, int delay) :
        base(id, ConditionType.Absolute, source, comment, 0f, deadBand, delay)
    {
        _subConditions = new SubCondition[1]
            {
                new SubCondition(SubAlarmType.Dsc)
            };
    }

    protected override void OnActive(SubCondition condition, Storage value, DateTime timeStamp)
    {
        if (condition.SubAlarmType != ActiveSubCondition)
        {
            if (condition.SubAlarmType != _tempType)
            {
                _timeStamp = timeStamp;
                _tempType = condition.SubAlarmType;
            }
            if (_delay == 0 || (timeStamp - _timeStamp).TotalMilliseconds > _delay)
            {
                if (ActiveSubCondition == SubAlarmType.None)
                {
                    _active = true;
                    _condLastActive = timeStamp;
                }
                _ack = false;
                ActiveSubCondition = condition.SubAlarmType;
                _current.Duration = timeStamp - SubCondLastActive;
                _current = new AlarmItem(timeStamp, condition.Message, true, ActiveSubCondition, condition.Severity, _id, _source);
                if (AlarmActive != null)
                {
                    foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList())
                    {
                        deleg.BeginInvoke(this, _current, null, null);
                    }
                }
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Value"));
                }
            }
        }
        else
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Value"));
            }
        }
    }

    protected override void OnInActive(Storage value)
    {
        if (ActiveSubCondition != SubAlarmType.None)
        {
            _active = false;
            ActiveSubCondition = SubAlarmType.None;
            _current.Duration = DateTime.Now - SubCondLastActive;
            _current = new AlarmItem(DateTime.Now, string.Concat("【", _current.AlarmText, "】", ALARMSTOP), false, SubAlarmType.None, Severity.Normal, _id, _source);
            if (AlarmActive != null)
            {
                foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList())
                {
                    deleg.BeginInvoke(this, _current, null, null);
                }
            }
        }
    }

    public Action SetFunction(Delegate tagChanged)
    {
        var _func = tagChanged as Func<bool>;
        if (_func != null)
        {
            return delegate
            {
                if (_enable)
                {
                    SubCondition condition = _subConditions[0];
                    if (condition.IsEnabled)
                    {
                        if (_func())
                        {
                            OnActive(condition, Storage.Empty, DateTime.Now);
                            return;
                        }
                    }
                    OnInActive(Storage.Empty);
                }
            };
        }
        else
            return null;
    }

    public override void Dispose()
    {
        base.Dispose();
        PropertyChanged = null;
    }

    public override AlarmType AlarmType
    {
        get
        {
            return AlarmType.Complex;
        }
    }

    public override bool AddSubCondition(SubCondition condition)
    {
        switch (condition.SubAlarmType)
        {
            case SubAlarmType.Dsc:
                _subConditions[0] = condition;
                return true;
            default:
                return false;
        }
    }

    public override bool RemoveSubCondition(SubCondition condition)
    {
        switch (condition.SubAlarmType)
        {
            case SubAlarmType.Dsc:
                _subConditions[0] = SubCondition.Empty;
                return true;
            default:
                return false;
        }
    }

}
